home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume17 / remind / part01 next >
Encoding:
Internet Message Format  |  1991-02-19  |  56.6 KB

  1. From: dfs@doe.carleton.ca (David F. Skoll)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i003:  remind - A replacement for calendar, Part01/04
  4. Message-ID: <1991Feb19.162725.16131@sparky.IMD.Sterling.COM>
  5. Date: 19 Feb 91 16:27:25 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 82b040d5 c245498c 552796f6 062f4573
  8.  
  9. Submitted-by: David F. Skoll <dfs@doe.carleton.ca>
  10. Posting-number: Volume 17, Issue 3
  11. Archive-name: remind/part01
  12.  
  13. Remind is a sophisticated replacement for calendar(1).  It features
  14. advanced date calculation routines, sophisticated handling of holidays,
  15. and "timed reminders" which you can set to pop up on your screen at specific
  16. times.  It also allows administrators to create system-wide reminders and
  17. have reminders mailed automatically to users.
  18.  
  19. Remind has been successfully compiled on Sun 3 and Sun 4 machines under
  20. SunOS 4.0 and 4.1, on a 386-Xenix machine, under MS-DOS on an XT, on
  21. an Apollo workstation, and on various other SYSV and BSD machines.
  22.  
  23. David F. Skoll
  24. --
  25. #! /bin/sh
  26. # This is a shell archive.  Remove anything before this line, then feed it
  27. # into a shell via "sh file" or similar.  To overwrite existing files,
  28. # type "sh file -c".
  29. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  30. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  31. # If this archive is complete, you will see the following message at the end:
  32. #        "End of archive 1 (of 4)."
  33. # Contents:  README.DOS README.UNIX nextdate.c remind.1
  34. # Wrapped by kent@sparky on Tue Feb 19 10:16:40 1991
  35. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  36. if test -f 'README.DOS' -a "${1}" != "-c" ; then 
  37.   echo shar: Will not clobber existing file \"'README.DOS'\"
  38. else
  39. echo shar: Extracting \"'README.DOS'\" \(1206 characters\)
  40. sed "s/^X//" >'README.DOS' <<'END_OF_FILE'
  41. XREMIND 2.3 for MS-DOS
  42. X
  43. XFirst, read the files COPYRIGHT and WHATSNEW.23.
  44. X
  45. XREMIND was originally written for MS-DOS.  To compile it, you need the
  46. XMicrosoft C compiler (at least version 5.1) and the Microsoft MAKE
  47. Xutility.
  48. X
  49. XBefore compiling the software, check if it includes patches.  These are
  50. Xfiles called patch.xx.  If there are patches, apply them all by typing
  51. X
  52. Xcat patch.* | patch
  53. X
  54. Xon a Unix machine.  Then copy the software to your MS-DOS machine.
  55. X
  56. XTo compile the software, simply go to the source directory and type:
  57. X
  58. XMAKE REMIND.MAK
  59. X
  60. XThe file test.rem contains test reminders for verifying that REMIND's
  61. Xdate calculation routines are working correctly.  The file test.out
  62. Xcontains the result of running:  remind -dv test.rem 16 feb 1991
  63. X
  64. XNote that the MS-DOS version of REMIND operates slightly differently from
  65. Xthe UNIX version:  MS-DOS has no concept of file access date.  Thus, to
  66. Ximplement the "ONCE" keyword, REMIND will change the modification date
  67. Xof the top-level reminder file after it has run.  This is equivalent to
  68. Xperforming a "touch" of the file after running REMIND.
  69. X
  70. XAlso, the MS-DOS version does not queue AT reminders for timed activation.
  71. X--
  72. XDavid F. Skoll <dfs@doe.carleton.ca>
  73. X
  74. END_OF_FILE
  75. if test 1206 -ne `wc -c <'README.DOS'`; then
  76.     echo shar: \"'README.DOS'\" unpacked with wrong size!
  77. fi
  78. # end of 'README.DOS'
  79. fi
  80. if test -f 'README.UNIX' -a "${1}" != "-c" ; then 
  81.   echo shar: Will not clobber existing file \"'README.UNIX'\"
  82. else
  83. echo shar: Extracting \"'README.UNIX'\" \(2180 characters\)
  84. sed "s/^X//" >'README.UNIX' <<'END_OF_FILE'
  85. XREMIND version 2.3 for UNIX
  86. X
  87. XFirst, read the files COPYRIGHT and WHATSNEW.23
  88. X
  89. XBefore compiling the software, check if it includes patches.  These
  90. Xare files called patch.xx.  If there are patches, apply them all by
  91. Xtyping
  92. X
  93. Xcat patch.* | patch
  94. X
  95. XNext, examine the Makefile and change any parameters which need to be
  96. Xchanged for your system.  As it stands, the Makefile is set up for a
  97. XBSD system.
  98. X
  99. XTo compile REMIND, just go to the source directory and type "make".
  100. XThis creates the executable file "remind".  You can type "make CC=gcc"
  101. Xif you want to use the Gnu C Compiler, or you can edit the Makefile to
  102. Xmake gcc the default.
  103. X
  104. XThe file test.rem contains test reminders for verifying that REMIND's
  105. Xdate calculation routines are working correctly.  The file test.out
  106. Xcontains the result of running: remind -dv test.rem 16 feb 1991
  107. X
  108. XREMIND has been compiled on Sun3s and Sun4s under Sun OS 4.0, on an
  109. XIBM PC under MS-DOS and on a 386 Xenix system to name a few.  REMIND
  110. Xshould compile on most systems without difficulty.
  111. X
  112. XOnce remind has been compiled, install it in your favourite system
  113. Xdirectory.  Type "make install" to install the executable, and "make
  114. Xinstall.man" to install the manpage.  If you want to install the "kall"
  115. Xscript, type "make install.kall"
  116. X
  117. XTwo shell scripts, "remind-all.csh" and "remind-all.sh" are provided.
  118. XThese allow automatic mailing of reminders to all users who create a
  119. X$HOME/.reminders file.  These two scripts are equivalent; one is a
  120. X"sh" script and the other is a "csh" script.  Pick the one you want to
  121. Xuse, and follow the instructions in the opening comments of the
  122. Xscript.
  123. X
  124. XA shell script called "kall" is provided which kills processes
  125. Xspecified by command name rather than process ID.  You may have to
  126. Xedit it to work on your system, since the output of "ps" is not
  127. Xportable.  You can use this script to kill all background remind
  128. Xprocesses in your .logout script by using "kall remind" Note that this
  129. Xversion of "kall" is different from the version of kall distributed
  130. Xwith 2.2 - the new version requires an exact match of command name,
  131. Xnot just a command name which contains the specified
  132. Xstring.
  133. X
  134. X--
  135. XDavid F. Skoll <dfs@doe.carleton.ca>
  136. END_OF_FILE
  137. if test 2180 -ne `wc -c <'README.UNIX'`; then
  138.     echo shar: \"'README.UNIX'\" unpacked with wrong size!
  139. fi
  140. # end of 'README.UNIX'
  141. fi
  142. if test -f 'nextdate.c' -a "${1}" != "-c" ; then 
  143.   echo shar: Will not clobber existing file \"'nextdate.c'\"
  144. else
  145. echo shar: Extracting \"'nextdate.c'\" \(8719 characters\)
  146. sed "s/^X//" >'nextdate.c' <<'END_OF_FILE'
  147. X#include "defines.h"
  148. X#include "globals.h"
  149. X#include "protos.h"
  150. X
  151. X/***************************************************************/
  152. X/*                                                             */
  153. X/*  int TryNextDate(int *retday, int *retmon, int *retyr,      */
  154. X/*                  int startday, int startmon, int startyr,   */
  155. X/*                  int conday, int conmon, int conyr,         */
  156. X/*                  int wkday, int cons, int inc)              */
  157. X/*                                                             */
  158. X/*  This function tries to find the next date satisfying       */
  159. X/*  the given constraints.  Returns                            */
  160. X/*  0 for success.  Returns non-zero if a constraint would     */
  161. X/*  be violated.  Note that if DAY and WEEKDAY are both        */
  162. X/*  constrained, then MONTH and YEAR may be violated.          */
  163. X/*  Otherwise, all constraints are honoured.                   */
  164. X/*  The starting point for the search is thisday, etc.         */
  165. X/*                                                             */
  166. X/*  If inc is non-zero, then the search begins from the day    */
  167. X/*  after the specified date.  Note that this function assumes */
  168. X/*  that the given date is valid.                              */
  169. X/*                                                             */
  170. X/***************************************************************/
  171. X#ifdef __STDC__
  172. Xint TryNextDate(int *retday, int *retmon, int *retyr,
  173. X        int d, int m, int y,
  174. X        int conday, int conmon, int conyr,
  175. X        int wkday, int cons, int inc)
  176. X#else
  177. Xint TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
  178. X                wkday, cons, inc)
  179. X     int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
  180. X     
  181. X#endif
  182. X
  183. X{
  184. X   int jul, jul2;
  185. X   int dd = d, mm = m, yy = y;
  186. X
  187. X   if (inc)
  188. X   {
  189. X      d++;
  190. X      if (d > DaysInMonth(m, y)) {
  191. X     m++; d = 1;
  192. X     if (m > 11) {
  193. X        y++; m = 0;
  194. X     }
  195. X      }
  196. X   }
  197. X
  198. X
  199. X   switch (cons & 15) {
  200. X
  201. X      case 0:  /* No constraints - just use the start date */
  202. X     *retday = d;
  203. X     *retmon = m;
  204. X     *retyr  = y;
  205. X     return 0;
  206. X
  207. X      case 1: /* Day constrained to be d */
  208. X     *retday = conday;
  209. X     if (d > conday) {
  210. X        m++;
  211. X        if (m > 11) {y++; m=0;}
  212. X     }
  213. X     while (conday > DaysInMonth(m, y)) {
  214. X        m++;
  215. X        if (m > 11) {y++; m=0;}
  216. X     }
  217. X     *retmon = m;
  218. X     *retyr = y;
  219. X     return 0;
  220. X
  221. X      case 2: /* Month constrained to be m */
  222. X     *retmon = conmon;
  223. X     if (m > conmon) {y++; d = 1;}
  224. X     else if (m < conmon) d = 1;
  225. X     *retday = d;
  226. X     *retyr = y;
  227. X     return 0;
  228. X
  229. X      case 3: /* Month and day constrained */
  230. X     *retmon = conmon;
  231. X     *retday = conday;
  232. X     if (m > conmon || (m == conmon && d > conday)) y++;
  233. X     while (conday > DaysInMonth(conmon, y)) y++;
  234. X     *retyr = y;
  235. X     return 0;
  236. X
  237. X      case 4: /* Year alone constrained */
  238. X     if (y > conyr) return 1;
  239. X     *retyr = conyr;
  240. X     if (y < conyr) {
  241. X        *retmon = 0;
  242. X        *retday = 1;
  243. X     }
  244. X     else {
  245. X        *retmon = m;
  246. X        *retday = d;
  247. X     }
  248. X     return 0;
  249. X
  250. X      case 5: /* Year and day constrained */
  251. X     if (y > conyr) return 1;
  252. X     *retyr = conyr;
  253. X     *retday = conday;
  254. X     if (y < conyr) {
  255. X        *retmon = 0;
  256. X        return 0;
  257. X     }
  258. X     if (d > conday) {
  259. X       m++;
  260. X       if (m > 11) return 1;
  261. X     }
  262. X     while (conday > DaysInMonth(m, y)) {
  263. X        m++;
  264. X        if (m > 11) return 1;
  265. X     }
  266. X     *retmon = m;
  267. X     return 0;
  268. X
  269. X      case 6: /* Year and month constrained */
  270. X     if (y > conyr || (y == conyr && m > conmon)) return 1;
  271. X     *retyr = conyr;
  272. X     *retmon = conmon;
  273. X     if (y < conyr || (y == conyr && m < conmon)) {
  274. X        *retday = 1;
  275. X        return 0;
  276. X     }
  277. X     *retday = d;
  278. X     return 0;
  279. X
  280. X      case 7: /* Year, month and day constrained */
  281. X     *retday = conday;
  282. X     *retmon = conmon;
  283. X     *retyr = conyr;
  284. X     if (y > conyr || (y == conyr && m > conmon) ||
  285. X         (y == conyr && m == conmon && d > conday)) return 1;
  286. X     return 0;
  287. X
  288. X      case 8: /* Only the weekday constrained.  Let's go to Julian mode */
  289. X     jul = Julian(d, m, y);
  290. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  291. X     FromJulian(jul, retday, retmon, retyr);
  292. X     return 0;
  293. X
  294. X      case 9: /* GASP! day and weekday constrained .. bleah! */
  295. X     /* First, try last month. */
  296. X     jul2 = Julian(d, m, y);
  297. X     if (m != 0 || y != BASE)
  298. X     {
  299. X        mm--;
  300. X        if (mm < 0) {yy--; mm = 11;}
  301. X
  302. X        /* If there are fewer days in month than required, it
  303. X           can't possibly match.  */
  304. X        if (conday <= DaysInMonth(mm, yy)) {
  305. X           jul = Julian(conday, mm, yy);
  306. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  307. X           if (jul >= jul2) { /* SUCCESS! */
  308. X          FromJulian(jul, retday, retmon, retyr);
  309. X          return 0;
  310. X           }
  311. X        }
  312. X     }
  313. X     /* Didn't work - try this month */
  314. X     if (conday <= DaysInMonth(m, y)) {
  315. X        jul = Julian(conday, m, y);
  316. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  317. X        if (jul >= jul2) { /* SUCCESS! */
  318. X           FromJulian(jul, retday, retmon, retyr);
  319. X           return 0;
  320. X        }
  321. X     }
  322. X     /* Argh!  Try next available month */
  323. X     mm = m;
  324. X     yy = y;
  325. X     do {
  326. X        mm++;
  327. X        if (mm > 11) {mm = 0; yy++;}
  328. X     } while (conday > DaysInMonth(mm, yy));
  329. X     jul = Julian(conday, mm, yy);
  330. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  331. X     FromJulian(jul, retday, retmon, retyr);
  332. X     return 0;
  333. X
  334. X      case 10: /* Month and Weekday constrained */
  335. X     if (m < conmon) {
  336. X        jul = Julian(1, conmon, y);
  337. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  338. X        FromJulian(jul, retday, retmon, retyr);
  339. X        return 0;
  340. X     } else if (m == conmon) {
  341. X        jul = Julian(d, conmon, y);
  342. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  343. X        FromJulian(jul, retday, retmon, retyr);
  344. X        if (*retmon != conmon) {
  345. X           jul = Julian(1, conmon, y+1);
  346. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  347. X           FromJulian(jul, retday, retmon, retyr);
  348. X        }
  349. X        return 0;
  350. X     } else { /* m > conmon */
  351. X        jul = Julian(1, conmon, y+1);
  352. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  353. X        FromJulian(jul, retday, retmon, retyr);
  354. X        return 0;
  355. X     }
  356. X
  357. X      case 11: /* Day, Month and Weekday constrained */
  358. X     jul2 = Julian(d, m, y);
  359. X
  360. X     /* Blip up to next valid year */
  361. X     while (conday > DaysInMonth(conmon, y)) y++;
  362. X
  363. X     /* Try this year */
  364. X     jul = Julian(conday, conmon, y);
  365. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  366. X     if (jul >= jul2) {
  367. X        FromJulian(jul, retday, retmon, retyr);
  368. X        return 0;
  369. X     }
  370. X
  371. X     /* Must be next year */
  372. X     jul = Julian(conday, conmon, y+1);
  373. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  374. X     FromJulian(jul, retday, retmon, retyr);
  375. X     return 0;
  376. X
  377. X      case 12: /* Weekday and year specified */
  378. X     if (y > conyr) return 1;
  379. X     if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
  380. X     jul = Julian(dd, mm, conyr);
  381. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  382. X     FromJulian(jul, retday, retmon, retyr);
  383. X     if (*retyr == conyr) return 0; else return 1;
  384. X
  385. X      case 13: /* Weekday, year and day specified */
  386. X     if (y > conyr+1 || (y > conyr && m>0)) return 1;
  387. X     jul2 = Julian(d, m, y);
  388. X     if (y > conyr ) {
  389. X        jul = Julian(conday, 11, conyr);
  390. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  391. X        if (jul >= jul2) {
  392. X           FromJulian(jul, retday, retmon, retyr);
  393. X           return 0;
  394. X        }
  395. X     } else if (y < conyr) {
  396. X        jul = Julian(conday, 0, conyr);
  397. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  398. X        FromJulian(jul, retday, retmon, retyr);
  399. X        return 0;
  400. X     }
  401. X     else {
  402. X        /* Try last month */
  403. X        if (m > 0) {
  404. X           mm = m - 1;
  405. X           while (conday > DaysInMonth(mm, y)) mm--;
  406. X           jul = Julian(conday, mm, y);
  407. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  408. X           if (jul >= jul2) {
  409. X          FromJulian(jul, retday, retmon, retyr);
  410. X          return 0;
  411. X           }
  412. X        }
  413. X        /* Try this month */
  414. X        if (conday <= DaysInMonth(m,y)) {
  415. X           jul = Julian(conday, m, y);
  416. X           while (!(wkday & (1 << (jul % 7)))) jul++;
  417. X           if (jul >= jul2) {
  418. X          FromJulian(jul, retday, retmon, retyr);
  419. X          return 0;
  420. X           }
  421. X        }
  422. X        /* Try next month */
  423. X        if (m == 11) return 1;
  424. X        m++;
  425. X        while (conday > DaysInMonth(m, y)) m++;
  426. X        jul = Julian(conday, m, y);
  427. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  428. X        FromJulian(jul, retday, retmon, retyr);
  429. X        return 0;
  430. X     }
  431. X
  432. X      case 14:  /* Weekday, Month and Year specified */
  433. X     if (y > conyr || (y == conyr && m > conmon)) return 1;
  434. X     if (conyr > y || (conyr == y && conmon > m)) {
  435. X        jul = Julian(1, conmon, conyr);
  436. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  437. X        FromJulian(jul, retday, retmon, retyr);
  438. X        if (*retmon == conmon) return 0; else return 1;
  439. X     } else {
  440. X        jul = Julian(d, m, y);
  441. X        while (!(wkday & (1 << (jul % 7)))) jul++;
  442. X        FromJulian(jul, retday, retmon, retyr);
  443. X        if (*retmon == conmon) return 0; else return 1;
  444. X
  445. X     }
  446. X
  447. X      case 15: /* Weekday, day, month and year specified */
  448. X     jul2 = Julian(d, m, y);
  449. X     jul = Julian(conday, conmon, conyr);
  450. X     while (!(wkday & (1 << (jul % 7)))) jul++;
  451. X     FromJulian(jul, retday, retmon, retyr);
  452. X     if (jul < jul2) return 1;
  453. X     return 0;
  454. X   }
  455. X}
  456. END_OF_FILE
  457. if test 8719 -ne `wc -c <'nextdate.c'`; then
  458.     echo shar: \"'nextdate.c'\" unpacked with wrong size!
  459. fi
  460. # end of 'nextdate.c'
  461. fi
  462. if test -f 'remind.1' -a "${1}" != "-c" ; then 
  463.   echo shar: Will not clobber existing file \"'remind.1'\"
  464. else
  465. echo shar: Extracting \"'remind.1'\" \(40229 characters\)
  466. sed "s/^X//" >'remind.1' <<'END_OF_FILE'
  467. X.TH REMIND 1 "18 February 1991"
  468. X.UC 4
  469. X.SH NAME
  470. Xremind \- a sophisticated reminder service
  471. X.SH SYNOPSIS
  472. X.B remind
  473. X[\fB\-n | \fB\-d\fR | \fB\-p\fR | \fB\-c\fR\fIn\fR [\fB\-w\fR\fIn\fR | \fB\-s\fR]]
  474. X[\fB\-voraq\fR]
  475. X.I filename
  476. X[\fIdate\fR]
  477. X.SH DESCRIPTION
  478. X.B remind
  479. Xreads the supplied
  480. X.I filename
  481. Xfor a list of reminders, and then issues reminders appropriate for
  482. Xthe current date.
  483. XEach reminder can consist of a message sent to standard output, or
  484. Xa program to be executed.
  485. X.SH OPTIONS
  486. X.TP
  487. X.B \-n
  488. XThe \fB\-n\fR flag causes \fBremind\fR to print the \fInext\fR occurrence
  489. Xof each reminder in a simple calendar format.  You can sort this by date by
  490. Xpiping the output through \fBsort(1)\fR.
  491. X.TP
  492. X.B \-d
  493. XThe
  494. X.B \-d
  495. Xflag causes
  496. X.B remind
  497. Xto enter a debugging mode.
  498. XIn this mode, each reminder in the reminder file is examined and its
  499. Xtrigger date is printed to standard output.  Also, some consistency
  500. Xchecking is done, and warnings are issued about constructs which could
  501. Xresult in slow execution times.
  502. X.TP
  503. X.B \-p
  504. XThe
  505. X.B \-p
  506. Xflag causes
  507. X.B remind
  508. Xto go into
  509. X.I purge
  510. Xmode.  This mode is incompatible with the
  511. X.B \-d
  512. Xflag.  It causes
  513. X.B remind
  514. Xto scan the reminder file and echo all reminders which have not expired
  515. Xto the standard output.  All expired reminders are echoed to the standard
  516. Xerror stream.
  517. X.TP
  518. X.B \-c\fR\fIn\fR
  519. XThe
  520. X.B \-c
  521. Xflag causes \fBremind\fR to generate a calendar with reminders indicated on
  522. Xthe calendar.  The calendar printout is formatted and sent to standard output.
  523. XIf you supply a number \fIn\fR from 1 to 12, 
  524. Xthen a calendar will be generated for
  525. X\fIn\fR months, starting with the current month.  The default is to
  526. Xproduce a calendar for one month only.  The
  527. X.B \-c
  528. Xoption is not compatible with the \fB\-p\fR or \fB\-d\fR options.
  529. X.TP
  530. X.B \-w\fR\fIn\fR
  531. XThe \fB\-w\fR flag, when used in conjunction with \fB\-c\fR,
  532. Xcauses \fBremind\fR to format the calendar for a device
  533. Xwhose output width is \fIn\fR columns.  The default is to produce a calendar
  534. Xfor an 80-column device.
  535. X.TP
  536. X.B \-s
  537. XThe \fB\-s\fB flag, when used in conjunction with \fB\-c\fR,
  538. Xcauses \fBremind\fR to send an unformatted "simple
  539. Xcalendar" listing to standard output.  This can be used if you wish to
  540. Xformat the calendar with another program rather than using \fBremind\fR's
  541. Xbuilt-in calendar format.
  542. X.TP
  543. X.B \-v
  544. XThe
  545. X.B \-v
  546. Xflag causes the debugging messages caused by
  547. X.B \-d
  548. Xto be printed in a verbose manner.  Also, any error messages issued by
  549. X.B remind
  550. Xare printed in verbose format.
  551. X.TP
  552. X.B \-o
  553. XThe
  554. X.B \-o
  555. Xflag causes
  556. X.B remind
  557. Xto ignore any
  558. X.B ONCE
  559. Xdirectives in the reminder file.
  560. X.TP
  561. X.B \-r
  562. XThe
  563. X.B \-r
  564. Xflag causes
  565. X.B remind
  566. Xto ignore any
  567. X.B RUN
  568. Xdirectives in the reminder file.
  569. X.TP
  570. X.B \-a
  571. XThe
  572. X.B \-a
  573. Xoption causes
  574. X.B remind
  575. Xnot to issue
  576. X.B AT
  577. Xreminders when the reminder file is read and processed, providing the
  578. X.B AT
  579. Xreminders would normally be queued.  This allows you to have
  580. X.B remind
  581. Xqueue
  582. X.B AT
  583. Xreminders without triggering them when it reads the file.
  584. X.TP
  585. X.B \-q
  586. XThe
  587. X.B \-q
  588. Xflag causes
  589. X.B remind
  590. Xnot to queue
  591. X.B AT
  592. Xreminders for triggering later in the day.  This prevents
  593. X.B remind
  594. Xfrom running as a daemon and popping up reminders as they are triggered.
  595. X.PP
  596. XIf you supply a
  597. X.I date
  598. Xon the command line, it must consist of
  599. X.I day month year
  600. Xwhere
  601. X.I day
  602. Xis the day of the month,
  603. X.I month
  604. Xis (at least the first three letters of) the English name of the month,
  605. Xand
  606. X.I year
  607. Xis a year (all 4 digits) from 1990 to 2075.  These components can appear
  608. Xin any order, but must be separated by spaces.  If a date is supplied,
  609. X.B remind
  610. Xuses it rather than the actual system date as its notion of "today."  You
  611. Xcan use this feature to test how reminders will appear in the future, or
  612. Xto produce a calendar for any month you choose.
  613. X.SH REMINDER FILES
  614. X.B Remind
  615. Xuses scripts called
  616. X.I reminder files
  617. Xto control its operation.  A sample reminder file is shown below:
  618. X.PP
  619. X.nf
  620. X    #!/usr/local/bin/remind
  621. X    # Sample file
  622. X    BANNER Hi there.  Here are your reminders:
  623. X
  624. X    # First some birthdays
  625. X    REM 6 Jan MSG David's birthday.
  626. X    REM 23 Nov +10 MSG El's birthday is %a.
  627. X
  628. X    # Next some housekeeping
  629. X    REM 1 -1 OMIT Sat Sun RUN do_backup
  630. X
  631. X    # Introduce some holidays
  632. X    OMIT 25 Dec +2 MSG %"Christmas%" is %b.
  633. X    OMIT  1 July MSG Canada Day
  634. X    OMIT 22 Nov 1990    # American Thanksgiving
  635. X
  636. X    # Business things
  637. X    REM 23 Nov 1990 +2 AT 10:00 +30 *15 MSG \\
  638. X    %"Meeting with Bill%" at %1 %b.%_Bring papers!
  639. X
  640. X.fi
  641. X.PP
  642. XNote that
  643. X.B remind
  644. Xignores blank lines and lines beginning with "#".  If the character '\\'
  645. Xis the LAST character on the line, it is treated as a continuation
  646. Xcharacter.  You can string many lines together using this character.
  647. XNote that if you use line continuation, then
  648. X.B remind
  649. Xuses the line number of the last line when printing diagnostic messages.
  650. X.PP
  651. XCommands, names of months, etc. can be typed in any
  652. Xmixture of upper- and lower-case.  The convention I use is to
  653. Xuse upper-case for
  654. X.B remind
  655. Xtokens like
  656. X.I
  657. XMSG, OMIT,
  658. Xetc., and mixed case for other words like
  659. X.I January
  660. Xand
  661. X.I Sunday.
  662. X.SH THE REM COMMAND
  663. XThe most-used command in a reminder file is the
  664. X.I REM
  665. Xcommand.  This command is used to denote a reminder.  There are many
  666. Xforms of the
  667. X.I REM
  668. Xcommand; they are represented by:
  669. X.PP
  670. X.RS
  671. XREM [ONCE] [\fIdate_spec\fR]
  672. X[\fIdelta\fR]
  673. X[\fIback\fR]
  674. X[\fIrepeat\fR]
  675. X[\fISKIP\fR | \fIBEFORE\fR | \fIAFTER\fR]
  676. X[OMIT \fIomit_list\fR]
  677. X[AT \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
  678. X[UNTIL \fIexpiry_date\fR]
  679. XMSG|RUN
  680. X.I body
  681. X.RE
  682. X.PP
  683. XThe parts of the \fIREM\fR command can be specified in any order, except
  684. Xthat the \fIbody\fR must come immediately after the \fIMSG\fR or \fIRUN\fR
  685. Xkeyword.
  686. X.SH DATE SPECIFICATIONS
  687. XThe
  688. X.I date_spec
  689. Xconsists of zero to four parts.  These parts are
  690. X.I day
  691. X(day of month),
  692. X.I month
  693. X(month name),
  694. X.I year
  695. Xand
  696. X.I weekday.
  697. X.I Month
  698. Xand
  699. X.I weekday
  700. Xare the English names of months and weekdays.  At least the first three
  701. Xcharacters must be used.  Case is irrelevant.  The following are examples
  702. Xof the various parts of a
  703. X.I date_spec:
  704. X.TP
  705. X.I day:
  706. X1, 22, 31, 14, 3
  707. X.TP
  708. X.I month:
  709. XJANUARY, feb, March, ApR, may, Aug
  710. X.TP
  711. X.I year:
  712. X1990, 1993, 2030, 95 (interpreted as 1995).  The year can range
  713. Xfrom 1990 to 2075.
  714. X.TP
  715. X.I weekday:
  716. XMonday, tue, Wed, THU, Friday, saturday, sundAy
  717. X.PP
  718. XNote that there can be several
  719. X.I weekday
  720. Xcomponents separated by spaces in a
  721. X.I date_spec.
  722. X.PP
  723. X.B INTERPRETATION OF DATE SPECIFICATIONS
  724. X.PP
  725. XThe following examples show how date specifications are interpreted.
  726. X.PP
  727. X1. Null date specification - the reminder is triggered every day.
  728. XThe trigger date for a specific run is simply the current system date.
  729. X.PP
  730. X2. Only
  731. X.I day
  732. Xpresent.  The reminder is triggered on the specified day of each month.
  733. XThe trigger date for a particular run is the closest such day to the
  734. Xcurrent system date.  For example:
  735. X.nf
  736. X    REM 1 MSG First of every month.
  737. X    REM 31 MSG 31st of every month that has 31 days.
  738. X.fi
  739. X.PP
  740. X3. Only
  741. X.I month
  742. Xpresent.  The reminder is triggered every day of the specified month.
  743. XExample:
  744. X.nf
  745. X    REM Feb MSG Every day in February
  746. X.fi
  747. X.PP
  748. X4.
  749. X.I day
  750. Xand
  751. X.I month
  752. Xpresent.  Examples:
  753. X.nf
  754. X    REM 6 Jan MSG Every 6th of January
  755. X    REM Feb 29 MSG Every 29th of February
  756. X.fi
  757. X.PP
  758. X5.  Only
  759. X.I year
  760. Xpresent. Example:
  761. X.nf
  762. X    REM 1991 MSG Every day in 1991
  763. X.fi
  764. X.PP
  765. X6.
  766. X.I year
  767. Xand
  768. X.I day
  769. Xpresent.  Examples:
  770. X.nf
  771. X    REM 1 1990 MSG 1st of every month in 1990
  772. X    REM 1992 23 MSG 23rd of every month in 1992
  773. X.fi
  774. X.PP
  775. X7.
  776. X.I year
  777. Xand
  778. X.I month
  779. Xpresent.  Examples:
  780. X.nf
  781. X    REM Feb 1991 MSG Every day in Feb 1991
  782. X    REM 1992 September MSG Every day in Sept 1992
  783. X.fi
  784. X.PP
  785. X8.
  786. X.I year, month
  787. Xand
  788. X.I day
  789. Xpresent.  Examples:
  790. X.nf
  791. X    REM 8 Jan 1991 MSG 8th January 1991.
  792. X    REM 1992 March 9 MSG 9th March 1992.
  793. X.fi
  794. X.PP
  795. X9.
  796. X.I weekday
  797. Xonly.  Examples:
  798. X.nf
  799. X    REM Sat MSG Every Saturday
  800. X    REM Mon Tue Wed Thu Fri MSG Every working day
  801. X    REM Monday Wednesday MSG Every Monday and Wednesday
  802. X.fi
  803. X.PP
  804. X10.
  805. X.I weekday
  806. Xand
  807. X.I day
  808. Xpresent.  Examples:
  809. X.nf
  810. X    REM Sat 1 MSG First Saturday of every month
  811. X    REM Mon Tue Wed Thu Fri 15 \\
  812. X        MSG 1st working day after 15th of every month
  813. X.fi
  814. X.PP
  815. X11.
  816. X.I weekday
  817. Xand
  818. X.I month
  819. Xpresent.  Examples:
  820. X.nf
  821. X    REM Mon March MSG Every Monday in March
  822. X    REM Mon Tue Wed Thu Fri Feb MSG Every working day in February
  823. X.fi
  824. X.PP
  825. X12.
  826. X.I weekday, month
  827. Xand
  828. X.I day
  829. Xpresent.  Examples:
  830. X.nf
  831. X    REM Mon 1 March MSG First Monday in March
  832. X    REM Sat Sun 15 July MSG First Sat or Sun on or after 15 July
  833. X.fi
  834. X.PP
  835. X13.
  836. X.I weekday
  837. Xand
  838. X.I year
  839. Xpresent.  Example:
  840. X.nf
  841. X    REM Sat Sun 1991 MSG Every Saturday and Sunday in 1991
  842. X.fi
  843. X.PP
  844. X14.
  845. X.I weekday, day
  846. Xand
  847. X.I year
  848. Xpresent.  Examples:
  849. X.nf
  850. X    REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
  851. X    REM Mon Tue Wed Thu Fri 1 1990 \\
  852. X        MSG 1st working day of every month in 1990
  853. X.fi
  854. X.PP
  855. X15.
  856. X.I weekday, month
  857. Xand
  858. X.I year
  859. Xpresent.  Example:
  860. X.nf
  861. X    REM Mon Wed 1991 Feb MSG Every Mon and Wed in Feb 1991.
  862. X.fi
  863. X.PP
  864. X16.
  865. X.I weekday, day, month
  866. Xand
  867. X.I year
  868. Xpresent.  Example:
  869. X.nf
  870. X    REM Mon Tue Wed Thu Fri 28 Oct 1990 \\
  871. X        MSG 1st working day on or after 28 October 1990.
  872. X.fi
  873. X.PP
  874. XNote that when
  875. X.I weekday
  876. Xand
  877. X.I day
  878. Xare specified,
  879. X.B remind
  880. Xchooses the first date on or after the specified
  881. X.I day
  882. Xwhich also satisfies the
  883. X.I weekday
  884. Xconstraint.  It does this by picking the first date on or after the specified
  885. X.I day
  886. Xwhich is listed in the list of
  887. X.I weekdays.
  888. XThus, a reminder like:
  889. X.PP
  890. X.nf
  891. X    REM Mon Tue 28 Oct 1990 MSG Hi
  892. X.fi
  893. X.PP
  894. Xwould be issued only on Monday, 29 October, 1990.  It would not be issued
  895. Xon Tuesday, 30 October, 1990, since the 29th is the first date to satisfy
  896. Xthe
  897. X.I weekday
  898. Xconstraints.
  899. X.PP
  900. X.B BACKWARD SCANNING
  901. X.PP
  902. XSometimes, you need to incorporate "backward scanning" into your date
  903. Xspecification.  This is accomplished with the
  904. X.I back
  905. Xpart of the reminder specification.  If present, the
  906. X.I back
  907. Xis specified as a number preceded by one or two minus signs.  This causes
  908. X.B remind
  909. Xto compute the trigger date as usual, and then move back the specified
  910. Xnumber of days.  For example:
  911. X.PP
  912. X.nf
  913. X    REM Mon 1 -7 MSG Last Monday of every month.
  914. X.fi
  915. X.PP
  916. XThis works by finding the first Monday of every month, and then moving
  917. X"back" seven days.  This results in the last Monday of the previous
  918. Xmonth.  (Warning:  If you have global 
  919. X.I OMITs, 
  920. Xthis might not work - see
  921. Xthe 
  922. X.I OMIT 
  923. Xcommand.  In this case, you can use the "definite \fIback\fR" which consists
  924. Xof a number preceded by two minus signs like \-\-7)
  925. X.PP
  926. XAnother example is:
  927. X.PP
  928. X.nf
  929. X    REM 1 -1 MSG Last day of every month.
  930. X.fi
  931. X.PP
  932. XSince we don't know how many days are in a month, to get to the last day
  933. Xof a month, we go to the first day of the next month and then move back
  934. Xone day.
  935. X.PP
  936. X.B Remind
  937. Xwill automatically scan forwards and backwards until it finds a suitable
  938. Xtrigger date.  Note that large
  939. X.I back
  940. Xvalues can lead to a lot of backtracking and slow the execution of
  941. X.B remind.
  942. X.PP
  943. X.B ADVANCE WARNING
  944. X.PP
  945. X.B Remind
  946. Xcan warn you of an upcoming reminder as far in advance as you desire.  This
  947. Xis specified by a
  948. X.I delta,
  949. Xwhich is a positive number preceded by one or two "+" signs.  For example:
  950. X.PP
  951. X.nf
  952. X    REM 8 Jan 1992 +3 MSG Test1
  953. X    REM 1 +1 MSG Test2
  954. X.fi
  955. X.PP
  956. XThe reminder "Test1" will be triggered on the 8th of January, 1992, as well
  957. Xas the 3 days preceding it.  All told, "Test1" will be triggered on the
  958. X5th through the 8th of January, 1992.
  959. X.PP
  960. XThe reminder "Test2" will be triggered on the first day of every month, as
  961. Xwell as the day before.  In effect, "Test2" will be triggered on the first
  962. Xand last day of every month.
  963. X.PP
  964. X.I Delta
  965. Xand
  966. X.I back
  967. Xcan be combined:
  968. X.PP
  969. X.nf
  970. X    REM Mon 1 --7 ++3 MSG Test3
  971. X.fi
  972. X.PP
  973. XThe reminder "Test3" will be triggered on the last Monday of every month,
  974. Xas well as the three days preceding it.
  975. X.PP
  976. XSee "The OMIT Command" for an explanation of the distinction between the "-"
  977. Xand "--" forms of the \fIback\fR, and the "+" and "++" forms of the
  978. X\fIdelta\fR.
  979. X.PP
  980. X.B REPEATING REMINDERS
  981. X.PP
  982. XThe
  983. X.I repeat
  984. Xcomponent in a reminder is a number preceded by an asterisk; for example,
  985. X"*14".  The
  986. X.I repeat
  987. Xis used to remind you of events which occur regularly after a specified
  988. Xstart date.  For example, suppose you get paid every second Thursday,
  989. Xand that your last payday was 8 November 1990.  The following reminder
  990. Xwould remind you of each payday 3 days in advance:
  991. X.PP
  992. X.nf
  993. X    REM 8 Nov 1990 *14 +3 MSG Payday is %b!
  994. X.fi
  995. X.PP
  996. XThe
  997. X.I repeat
  998. Xcomponent of "*14" would cause the reminder to be triggered every 14
  999. Xdays from the start date.
  1000. X.PP
  1001. XIn order to use a
  1002. X.I repeat,
  1003. Xyou must fully specify the start date.  That means that if
  1004. Xyou use a
  1005. X.I repeat,
  1006. Xyou must specify the
  1007. X.I month, day
  1008. Xand
  1009. X.I year.
  1010. XYou can also specify
  1011. X.I weekday, back
  1012. Xand
  1013. X.I local OMITs
  1014. Xbut these only affect the calculation of the start date.  Once the
  1015. Xstart date is calculated, the reminder is issued regularly every
  1016. X.I repeat
  1017. Xdays.  Note, in particular, that once the start date is calculated,
  1018. X.B remind
  1019. Xignores local and global
  1020. X.I OMITs
  1021. Xwhen calculating the trigger date.  The final trigger date is strictly
  1022. Xa multiple of
  1023. X.I repeat
  1024. Xdays from the start date.  The only exceptions are those cases covered
  1025. Xby the \fIBEFORE, AFTER\fR and \fISKIP\fR keywords, discussed in the
  1026. Xnext section.
  1027. X.PP
  1028. X.B THE BEFORE, AFTER AND SKIP KEYWORDS
  1029. X.PP
  1030. XShould a reminder's trigger date happen to fall on an OMITted day, the
  1031. Xdefault action is to go ahead and trigger the reminder anyway.  For example,
  1032. Xsuppose you have a meeting every Tuesday.  Consider the following:
  1033. X.PP
  1034. X.nf
  1035. X    OMIT 1 Jan MSG New Year's Day
  1036. X    OMIT 25 December MSG Christmas
  1037. X    REM Tue AT 13:00 MSG Code review meeting.
  1038. X.fi
  1039. X.PP
  1040. XEven though Christmas 1990 is on a Tuesday, you will still be reminded
  1041. Xof a code review meeting on that day.  Surely that is not desirable.  You
  1042. Xcan tell \fBremind\fR to skip reminders which fall on OMITted days with the
  1043. X.I SKIP
  1044. Xkeyword.  Assuming we have the same \fIOMIT\fR commands, then:
  1045. X.PP
  1046. X.nf
  1047. X    REM Tue SKIP AT 13:00 MSG Code review meeting.
  1048. X.fi
  1049. X.PP
  1050. Xwould be triggered every Tuesday, but not on Christmas or New Year's
  1051. XDay, because both of these holidays happen to fall on Tuesdays.
  1052. X.PP
  1053. XIn some situations, we don't want to skip the reminder; we want to move
  1054. Xit to just before or just after a holiday.  Consider these examples:
  1055. X.PP
  1056. X.nf
  1057. X    REM Fri AFTER OMIT Sat Sun MSG Do your backup!
  1058. X.fi
  1059. X.PP
  1060. XThis reminder is normally triggered every Friday.  However, if a particular
  1061. XFriday happens to be a holiday, it will be triggered on the Monday after
  1062. Xthe holiday instead.  Note that the \fIAFTER\fR keyword keeps scanning
  1063. Xforwards until it hits a day which is not in the global or local \fIOMIT\fR
  1064. Xlists.  (Of course, if both the Friday and Monday are holidays, then the
  1065. Xreminder would be deferred until Tuesday, and so on.)
  1066. X.PP
  1067. X.nf
  1068. X    REM Fri BEFORE MSG Do your backup!
  1069. X.fi
  1070. X.PP
  1071. XThis is similar, except that the reminder is issued on the previous Thursday
  1072. Xif a particular Friday happens to be a holiday.  This form, too, will
  1073. Xmove back to Wednesday if Thursday also happens to be a holiday, and so on.
  1074. X.PP
  1075. XNote:  These keywords skip both local and global \fIOMIT\fRs.  Also,
  1076. X\fBremind\fR will complain about certain illegal constructions, such as:
  1077. X.PP
  1078. X.nf
  1079. X    REM Mon SKIP OMIT Mon MSG Impossible!
  1080. X.fi
  1081. X.PP
  1082. XIf \fBremind\fR makes too many attempts to find a trigger date for
  1083. Xcertain forms, it assumes that no satisfiable date exists, and will warn
  1084. Xyou to check the date specification.  In practice, this should never happen.
  1085. X.PP
  1086. X.B THE UNTIL KEYWORD
  1087. X.PP
  1088. XThe \fIUNTIL\fR keyword can be used to force a reminder to expire at a
  1089. Xparticular date.  It must be followed by a \fIyear\fR, \fImonth\fR and
  1090. X\fIday\fR specifying the expiry date.  Here are some examples:
  1091. X.PP
  1092. XSuppose you have a conference from 25 Feb 1991 to 1 March 1991.  You
  1093. Xcould use:
  1094. X.PP
  1095. X.nf
  1096. X    REM 25 Feb 1991 *1 UNTIL 1 Mar 1991 MSG Conference today!
  1097. X.fi
  1098. X.PP
  1099. XYou must include the "*1" to have the reminder repeated every day
  1100. Xduring the conference.  If you did not include the "*1", then the
  1101. Xreminder would only have been issued on 25 Feb 1991.
  1102. X.PP
  1103. XSuppose you have jury duty from 4-15 March 1991, not including weekends.
  1104. XSuppose further that you wish to be reminded of this duty starting on 1
  1105. XMarch 1991 (hence the "++3"):  (See the section "Substitution" for an
  1106. Xexplanation of all the percent signs.)
  1107. X.PP
  1108. X.nf
  1109. X    REM 4 Mar 1991 ++3 *1 OMIT Sat Sun SKIP UNTIL 15 Mar 1991 \\
  1110. X    MSG %"Jury duty%" %b.
  1111. X.fi
  1112. X.PP
  1113. XFinally, suppose you have a class every Tuesday and Thursday until 30 May
  1114. X1991:
  1115. X.PP
  1116. X.nf
  1117. X    REM Tue Thu UNTIL 30 May 1991 MSG Class tonight.
  1118. X.fi
  1119. X.PP
  1120. X.B THE MSG KEYWORD
  1121. X.PP
  1122. XThe
  1123. X.I MSG
  1124. Xkeyword causes the remaining part of the line to be passed through a
  1125. Xsubstitution filter and then printed to standard output whenever the
  1126. Xreminder is triggered.  See the section "Substitution" for more information
  1127. Xabout the substitution filter.
  1128. X.PP
  1129. X.B THE RUN KEYWORD
  1130. X.PP
  1131. XThe
  1132. X.I RUN
  1133. Xkeyword causes the remaining part of the line to be passed through the
  1134. Xsubstitution filter and then passed to the default shell for execution
  1135. Xwhenever the reminder is triggered.  If the
  1136. X.B \-r
  1137. Xcommand-line option is specified, all
  1138. X.I REM
  1139. Xcommands with the
  1140. X.I RUN
  1141. Xkeyword are ignored.
  1142. X.PP
  1143. X.B
  1144. XGETTING REMINDED ONLY ONCE PER DAY
  1145. X.PP
  1146. XIf you run
  1147. X.B remind
  1148. Xfrom your
  1149. X.I .login
  1150. Xscript, you may only want certain reminders to be run once per day, not
  1151. Xonce per login.  Typically, this is used to control
  1152. X.I RUN
  1153. Xcommands so that they only execute once per day.  To specify this,
  1154. Xplace the
  1155. X.I ONCE
  1156. Xkeyword in the reminder file.  When
  1157. X.B remind
  1158. Xencounters a
  1159. X.I ONCE
  1160. Xkeyword, it checks the last-access date of the reminder file.  If it is
  1161. Xequal to the current date,
  1162. X.B remind
  1163. Xassumes that the reminder file has already been run once, and ignores the
  1164. Xreminder.  If you start
  1165. X.B remind
  1166. Xwith the
  1167. X.B \-o
  1168. Xcommand-line option,
  1169. X.B remind
  1170. Xignores the
  1171. X.I ONCE
  1172. Xkeyword.
  1173. X.PP
  1174. X.B LOCALLY OMITTING WEEKDAYS
  1175. X.PP
  1176. XA
  1177. X.I REM
  1178. Xcommand containing the
  1179. X.I OMIT
  1180. Xkeyword followed by a list of weekdays causes the
  1181. X.I delta
  1182. Xand
  1183. X.I back
  1184. Xto ignore the specified weekdays when counting days.  This is called a
  1185. X.I local OMIT.
  1186. XFor example:
  1187. X.PP
  1188. X.nf
  1189. X    REM 1 +1 OMIT Sat Sun MSG Test4
  1190. X.fi
  1191. X.PP
  1192. XThis reminder prints "Test4" on the first day of every month, as well
  1193. Xas the previous day.  If, however, the first day of the month falls on
  1194. Xa Sunday or Monday, the reminder is also triggered on the previous
  1195. XFriday, since the
  1196. X.I delta
  1197. Xof +1 does not count Saturdays or Sundays when moving backwards.  Here's
  1198. Xanother example:
  1199. X.PP
  1200. X.nf
  1201. X    REM 1 -1 +1 OMIT Sat Sun MSG Test5
  1202. X.fi
  1203. X.PP
  1204. XThis reminder is triggered on the last working day of each month, as well
  1205. Xas the working day preceding it.  Let's look at it in detail:
  1206. X.PP
  1207. XThe
  1208. X.I day
  1209. Xof "1" specifies the first day of each month.  The
  1210. X.I back
  1211. Xof "-1" tells
  1212. X.B remind
  1213. Xto go backwards by one day, not counting Saturday and Sunday as it moves.
  1214. XThis takes us the the last working day of the preceding month, which is the
  1215. Xtrigger date.  The
  1216. X.I delta
  1217. Xof "+1" ensures that the reminder will be triggered on the day preceding
  1218. Xthis trigger date also.  Finally, if the trigger date happens to be
  1219. Xa Monday, the
  1220. X.I delta
  1221. Xcombined with the
  1222. X.I local OMIT
  1223. Xcauses the reminder to be triggered on the Friday (and Saturday and Sunday)
  1224. Xpreceding the trigger date.
  1225. X.PP
  1226. X.B THE AT KEYWORD
  1227. X.PP
  1228. XReminders with the
  1229. X.I AT
  1230. Xkeyword are called "timed reminders" or "AT reminders."  The
  1231. X.I AT
  1232. Xkeyword must be followed by a
  1233. X.I time,
  1234. Xwhich is a time in 24-hour format, from 0:00 to 23:59.  The
  1235. X.I time
  1236. Xmust be of the form \fIhh\fR:\fImm\fR.
  1237. XAlso, after the
  1238. X.I AT
  1239. Xkeyword, you can supply a
  1240. X.I tdelta
  1241. Xand a
  1242. X.I trepeat.
  1243. XThese have the same form as a
  1244. X.I delta
  1245. Xand a
  1246. X.I repeat.
  1247. XIn other words, a
  1248. X.I tdelta
  1249. Xis a number preceded by a "+" sign, and a
  1250. X.I trepeat
  1251. Xis a number preceded by an asterisk.
  1252. X.PP
  1253. XWhen
  1254. X.B remind
  1255. Xencounters a timed reminder, it examines the actual trigger date.  This
  1256. Xis the date specified by the date_spec, not counting any
  1257. X.I delta
  1258. Xwhich may be present.  If the trigger date is the same as the current
  1259. Xdate, the timed reminder will be placed on a queue in addition to
  1260. Xbeing triggered like a normal reminder.  (If you supply the
  1261. X.B \-a
  1262. Xcommand-line option, a timed reminder which would be queued will not
  1263. Xbe triggered like a normal reminder.)  After
  1264. X.B remind
  1265. Xhas finished processing the reminder file, it starts up a background
  1266. Xprocess to trigger all the queued timed reminders.  As each reminder's
  1267. Xtrigger time is reached, it is triggered.  Thus, you can have
  1268. X.B remind
  1269. Xissue reminders just before important meetings or time-sensitive tasks.
  1270. X.PP
  1271. XThe
  1272. X.I tdelta
  1273. Xand
  1274. X.I trepeat
  1275. Xare interpreted in minutes.  This is how they work:
  1276. X.PP
  1277. X.nf
  1278. X    REM AT 17:00 +60 *15 MSG Hello!
  1279. X.fi
  1280. X.PP
  1281. XThis timed reminder has a trigger time of 5:00pm.  It is also triggered
  1282. Xone hour before 5:00pm (because of the
  1283. X.I tdelta
  1284. Xof +60)
  1285. Xand every 15 minutes thereafter until 5:00pm (because of the
  1286. X.I trepeat
  1287. Xof +15.)  All told, the reminder would be triggered at 4:00pm, 4:15pm,
  1288. X4:30pm, 4:45pm and 5:00pm.
  1289. X.PP
  1290. X.nf
  1291. X    REM Fri AT 17:00 +45 *30 MSG Work ends at 5!!
  1292. X.fi
  1293. X.PP
  1294. XThis timed reminder would be placed on the queue every Friday.  It
  1295. Xwould be triggered at 4:15pm, 4:45pm and 5:00pm every Friday.  Note
  1296. Xthat a timed reminder is always triggered at the time specified
  1297. Xafter the
  1298. X.I AT
  1299. Xkeyword, even if the
  1300. X.I tdelta
  1301. Xis not a multiple of
  1302. X.I trepeat.
  1303. X.PP
  1304. XIf a reminder has a regular
  1305. X.I delta,
  1306. Xit will not be queued unless the current system date equals the actual
  1307. Xtrigger date.  Thus:
  1308. X.PP
  1309. X.nf
  1310. X    REM Fri +1 AT 17:00 MSG Go home at 5:00!
  1311. X.fi
  1312. X.PP
  1313. XOn Thursdays, this reminder would simply be treated as a regular reminder
  1314. Xand printed.  On Fridays, however, it would be queued for timed triggering.
  1315. XNote that the
  1316. X.B \-q
  1317. Xcommand-line option causes
  1318. X.B remind
  1319. Xto treat timed reminders as normal reminders, and not queue them.
  1320. X.SH THE OMIT COMMAND
  1321. X.I OMIT
  1322. Xexists as a separate command as well as a keyword within a
  1323. X.I REM
  1324. Xstatement.  When used as a separate command, it is called a
  1325. X.I global OMIT,
  1326. Xand has the following form:
  1327. X.RS
  1328. XOMIT
  1329. X.I day
  1330. X.I month
  1331. X[
  1332. X.I year
  1333. X]
  1334. X.RE
  1335. XThe arguments can be specified in any order.
  1336. X.PP
  1337. XThe form without the
  1338. X.I year
  1339. Xcomponent is used for holidays which fall on the same date each year.
  1340. XFor example:
  1341. X.PP
  1342. X.nf
  1343. X    OMIT 25 December    # Christmas
  1344. X    OMIT  1 January        # New Year's Day
  1345. X.fi
  1346. X.PP
  1347. X(Note that
  1348. X.I OMIT
  1349. Xcan have a following comment on the same line, unlike the
  1350. X.I REM
  1351. Xcommand.)
  1352. X.PP
  1353. XThe form with the
  1354. X.I year
  1355. Xcomponent is used for holidays which vary from year to year.  For example:
  1356. X.PP
  1357. X.nf
  1358. X    OMIT 12 October 1990    # Columbus Day 1990
  1359. X    OMIT 22 November 1990    # Thanksgiving Day 1990
  1360. X.fi
  1361. X.PP
  1362. XIn its debugging messages,
  1363. X.B remind
  1364. Xcalls the first form a
  1365. X.I partially-specified global OMIT
  1366. Xand the second form a
  1367. X.I fully-specified global OMIT.
  1368. X.PP
  1369. XThe dates specified by
  1370. X.I global OMITs
  1371. Xare omitted by the
  1372. X.I back
  1373. Xand
  1374. X.I delta
  1375. Xportions of a reminders, in addition to any
  1376. X.I local OMITs.
  1377. XFor example:
  1378. X.PP
  1379. X.nf
  1380. X    OMIT 25 December
  1381. X    REM 26 +1 OMIT Sat Sun MSG Test6
  1382. X.fi
  1383. X.PP
  1384. XThis would issue a reminder on the 26th of each month, as well as the
  1385. Xpreceding working day.  Also, on the 24th of December 1990, the reminder
  1386. Xwould be issued.  Even though the 25th of December 1990 is a Tuesday, the
  1387. X.I global OMIT
  1388. Xwould cause the
  1389. X.I delta
  1390. Xto skip it.
  1391. X.PP
  1392. XHowever, if you use the "--" and "++" forms of \fIback\fR and \fIdelta\fR,
  1393. Xthen OMITted days are not skipped - strict date subtraction is performed.
  1394. XThus, to have a reminder issued on the last Monday of every month, regardless
  1395. Xof any \fIglobal OMITs\fR in force, you could use:
  1396. X.PP
  1397. X.nf
  1398. X    REM 1 Mon --7 MSG Forced to be last Monday in month
  1399. X.fi
  1400. X.PP
  1401. XIf you want the reminder to be issued on the last Monday of every month,
  1402. Xunless it is a holiday, in which case the reminder should be issued the
  1403. Xfollowing Tuesday, use:
  1404. X.PP
  1405. X.nf
  1406. X    REM 1 Mon --7 AFTER MSG Example!
  1407. X.fi
  1408. X.PP
  1409. X.I Global OMITs
  1410. Xare in force for all reminders following them in the reminder file until
  1411. Xa CLEAR-OMIT-CONTEXT or POP-OMIT-CONTEXT command is encountered.  Thus,
  1412. Xyou could have a series of reminders for which
  1413. X.I global OMITs
  1414. Xare inappropriate (such as birthdays or reminders which rely on
  1415. X.I back
  1416. Xto get to a specific weekday) ahead of any
  1417. X.I global OMITs,
  1418. Xwith business reminders (for which omission of holidays is appropriate)
  1419. Xfollowing the
  1420. X.I global OMITs.
  1421. X.PP
  1422. XFor convenience, you can include a \fIdelta\fR and a \fIMSG\fR or \fIRUN\fR
  1423. Xtoken in a global \fIOMIT\fR.  This is useful to avoid duplication of holiday
  1424. Xentries.  For example, the line:
  1425. X.PP
  1426. X.nf
  1427. X    OMIT 25 Dec +2 MSG %"Christmas%" is %b.
  1428. X.fi
  1429. X.PP
  1430. Xis exactly equivalent to:
  1431. X.PP
  1432. X.nf
  1433. X    OMIT 25 Dec
  1434. X    REM 25 Dec +2 MSG %"Christmas%" is %b.
  1435. X.fi
  1436. X.SH CONTROLLING THE OMIT CONTEXT
  1437. XIn many cases, it is convenient to temporarily change the \fIglobal OMITs\fR
  1438. Xwhich are in force.  This allows you to easily isolate holidays to act only
  1439. Xon certain reminders, or to temporarily introduce a \fIglobal OMIT\fR for a
  1440. Xspecial-case reminder.  Three commands allow you to do this:
  1441. X.PP
  1442. X.I CLEAR-OMIT-CONTEXT
  1443. Xdeletes all the \fIglobal OMITs\fR and starts you off with a clean slate.
  1444. X.PP
  1445. X.I PUSH-OMIT-CONTEXT
  1446. Xsaves all the \fIglobal OMITs\fR on an internal stack and leaves the current
  1447. X\fIglobal OMITs\fR in effect.
  1448. X.PP
  1449. X.I POP-OMIT-CONTEXT
  1450. Xrestores the \fIglobal OMITs\fR which were in effect at the time of the last
  1451. Xmatching \fIPUSH-OMIT-CONTEXT\fR command.
  1452. X.PP
  1453. XSuppose you have a block of reminders which require a clear OMIT context
  1454. Xto work properly, and which also introduce several \fIglobal OMITs\fR which
  1455. Xyou don't want to affect any other reminders.  The following fragment shows
  1456. Xhow to isolate these reminders:
  1457. X.PP
  1458. X.nf
  1459. X    # Sample fragment
  1460. X    PUSH-OMIT-CONTEXT   # Save for later
  1461. X    CLEAR-OMIT-CONTEXT  # Start out with clean slate
  1462. X
  1463. X    # Block of reminders goes here
  1464. X
  1465. X    POP-OMIT-CONTEXT    # Restore the saved OMITs
  1466. X    # Remaining reminders go here
  1467. X.fi
  1468. X.SH THE INCLUDE COMMAND
  1469. XThe
  1470. X.I INCLUDE
  1471. Xcommand has the following form:
  1472. X.PP
  1473. X.RS
  1474. XINCLUDE
  1475. X.I filename
  1476. X.RE
  1477. X.PP
  1478. XThis causes
  1479. X.B remind
  1480. Xto suspend the current file and read the contents of the specified
  1481. X.I filename.
  1482. XOnce that file has been read,
  1483. X.B remind
  1484. Xcontinues reading the original file from where it left off.
  1485. X.I INCLUDE
  1486. Xcommands can be nested to a depth of 10.
  1487. X.PP
  1488. X.I INCLUDE
  1489. Xallows you or someone else to maintain a file of holidays or system-wide
  1490. Xreminders that everyone should get.  For example, your reminder file could
  1491. Xlook something like this:
  1492. X.PP
  1493. X.nf
  1494. X    #!/usr/local/bin/remind
  1495. X    #
  1496. X    # Place personal stuff here - birthdays, etc.
  1497. X
  1498. X    # Now get system-wide global OMITS (holidays)
  1499. X    INCLUDE /usr/share/holidays
  1500. X
  1501. X    # and system-wide reminders
  1502. X    INCLUDE /usr/share/reminders
  1503. X
  1504. X    # Place local business stuff here.
  1505. X.fi
  1506. X.PP
  1507. XThe
  1508. X.I ONCE
  1509. Xkeyword operates on the last-access date of the top-level file.
  1510. XThe access dates of
  1511. X.I INCLUDEd
  1512. Xfiles are not used to control the operation of the
  1513. X.I ONCE
  1514. Xkeyword.
  1515. X.SH SUBSTITUTION
  1516. XBefore being processed, the body of a
  1517. X.I REM
  1518. Xcommand is passed through a substitution filter.  The filter scans for
  1519. Xsequences "%x" (where "x" is any letter and certain other characters)
  1520. Xand performs substitutions as
  1521. Xshown below.  (All dates refer to the trigger date of the reminder.)
  1522. X.TP
  1523. X.B %a
  1524. Xis replaced with "on \fIweekday, day month, year\fR"
  1525. X.RS
  1526. XFor example, consider the reminder:
  1527. X.PP
  1528. XREM 18 Oct 1990 +4 MSG Meeting with Bob %a.
  1529. X.PP
  1530. XOn 16 October 1990, it would print "Meeting with Bob on Thursday, 18 October,
  1531. X1990."
  1532. X.PP
  1533. XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
  1534. X.PP
  1535. XOn 18 October 1990, it would print "Meeting with Bob today."
  1536. X.RE
  1537. X.TP
  1538. X.B %b
  1539. Xis replaced with "in \fIdiff\fR day's time" where
  1540. X.I diff
  1541. Xis the
  1542. X.B actual
  1543. Xnumber of days between the current date and the trigger date.
  1544. X(\fIOMITs\fR have no effect.)
  1545. X.RS
  1546. XFor example, consider:
  1547. X.PP
  1548. XREM 18 Oct 1990 +4 MSG Meeting with Bob %b.
  1549. X.PP
  1550. XOn 16 October 1990, it would print "Meeting with Bob in 2 days' time."
  1551. X.PP
  1552. XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
  1553. X.PP
  1554. XOn 18 October 1990, it would print "Meeting with Bob today."
  1555. X.RE
  1556. X.TP
  1557. X.B %c
  1558. Xis replaced with "on \fIweekday\fR"
  1559. X.RS
  1560. XExample: REM 18 Oct 1990 +4 MSG Meeting with Bob %c.
  1561. X.PP
  1562. XOn 16 October 1990, it would print "Meeting with Bob on Thursday."
  1563. X.PP
  1564. XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
  1565. X.PP
  1566. XOn 18 October 1990, it would print "Meeting with Bob today."
  1567. X.RE
  1568. X.TP
  1569. X.B %d
  1570. Xis replaced with "\fIday\fR", the day of the month.
  1571. X.TP
  1572. X.B %e
  1573. Xis replaced with "on \fIdd/mm/yyyy\fR"
  1574. X.TP
  1575. X.B %f
  1576. Xis replaced with "on \fImm/dd/yyyy\fR"
  1577. X.TP
  1578. X.B %g
  1579. Xis replaced with "on \fIweekday, day month\fR"
  1580. X.TP
  1581. X.B %h
  1582. Xis replaced with "on \fIdd/mm\fR"
  1583. X.TP
  1584. X.B %i
  1585. Xis replaced with "on \fImm/dd\fR"
  1586. X.TP
  1587. X.B %j
  1588. Xis replaced with "on \fIweekday, month day-th, year\fR"  This form appends the
  1589. Xcharacters "st", "nd", "rd" or "th" to the day of the month, as appropriate.
  1590. X.TP
  1591. X.B %k
  1592. Xis replaced with "on \fIweekday, month day-th\fR"
  1593. X.TP
  1594. X.B %l
  1595. Xis replaced with "on \fIyyyy/mm/dd\fR"
  1596. X.TP
  1597. X.B %m
  1598. Xis replaced with "\fImonth\fR", the name of the month.
  1599. X.TP
  1600. X.B %n
  1601. Xis replaced with the number (1 to 12) of the month.
  1602. X.TP
  1603. X.B %o
  1604. Xis replaced with " (today)" if and only if the current system date is the same
  1605. Xas the date being used by
  1606. X.B remind
  1607. Xas the current date.  Recall that you can specify a date for
  1608. X.B remind
  1609. Xto use on the command line.  This substitution is not generally useful in a
  1610. X.I REM
  1611. Xcommand, but is useful in a
  1612. X.I BANNER
  1613. Xstatement.  (See the section "The BANNER Command.)
  1614. X.TP
  1615. X.B %p
  1616. Xis replaced with "s" if the
  1617. X.I diff
  1618. Xbetween the current date and the trigger date is not 1.  You can use this
  1619. Xto construct reminders like:
  1620. X.RS
  1621. XREM 1 Jan +4 MSG %x day%p to go before New Year!
  1622. X.RE
  1623. X.TP
  1624. X.B %q
  1625. Xis replaced with "'s" if the
  1626. X.I diff
  1627. Xbetween the trigger date and the current date is 1.  Otherwise, it is replaced
  1628. Xwith "s'"  This can be used as follows:
  1629. X.RS
  1630. XREM 1 Jan +4 MSG New Year in %x day%q time!
  1631. X.RE
  1632. X.TP
  1633. X.B %r
  1634. Xis replaced with the day of the month (01 to 31) padded with a leading zero
  1635. Xif needed to pad to two digits.
  1636. X.TP
  1637. X.B %s
  1638. Xis replaced with "st", "nd", "rd" or "th" depending on the day of the month.
  1639. X.TP
  1640. X.B %t
  1641. Xis replaced with the number of the month (01 to 12) padded to two digits
  1642. Xwith a leading zero.
  1643. X.TP
  1644. X.B %u
  1645. Xis replaced with "on \fIweekday, day-th month, year\fR"  This is similar
  1646. Xto
  1647. X.B %a
  1648. Xexcept that "st", "nd", "rd" or "th" is added to the
  1649. X.I day
  1650. Xas appropriate.
  1651. X.TP
  1652. X.B %v
  1653. Xis replaced with "on \fIweekday, day-th month\fR"
  1654. X.TP
  1655. X.B %w
  1656. Xis replaced with "\fIweekday\fR", the name of the day of the week.
  1657. X.TP
  1658. X.B %x
  1659. Xis replaced with the
  1660. X.I diff
  1661. Xbetween the current date and the trigger date.  The
  1662. X.I diff
  1663. Xis defined as the actual number of days between these two dates;
  1664. X.I OMITs
  1665. Xare not counted.  (Strict date subtraction is performed.)
  1666. X.TP
  1667. X.B %y
  1668. Xis replaced with "\fIyear\fR", the year of the trigger date.
  1669. X.TP
  1670. X.B %z
  1671. Xis replaced with "\fIyy\fR", the last two digits of the year.
  1672. X.TP
  1673. X.B %_
  1674. X(percent-underscore) is replaced with a newline.  You can use this to
  1675. Xachieve multi-line reminders.
  1676. X.TP
  1677. X.B %1
  1678. Xis replaced with "now", "\fIm\fR minutes from now", "\fIm\fR minutes ago",
  1679. X"\fIh\fR hours from now", "\fIh\fR hours ago", "\fIh\fR hours and \fIm\fR
  1680. Xminutes from now" or "\fIh\fR hours and \fIm\fR minutes ago", as appropriate
  1681. Xfor a timed reminder.  Note that unless you specify the \fB\-a\fR option,
  1682. Xtimed reminders will be triggered like normal reminders, and thus a timed
  1683. Xreminder which occurred earlier in the day may be triggered.  This
  1684. Xcauses the need for the "...ago" forms.
  1685. X.TP
  1686. X.B %2
  1687. Xis replaced with "\fIhh\fR:\fImm\fRam" or "..pm" depending on the
  1688. X.I AT
  1689. Xtime of the reminder.
  1690. X.TP
  1691. X.B %3
  1692. Xis replaced with "\fIhh\fR:\fImm\fR" in 24-hour format.
  1693. X.TP
  1694. X.B %4
  1695. Xis replaced with "\fImm\fR" where \fImm\fR is the number of minutes between
  1696. X"now" and the time specified by \fIAT\fR.  If the \fIAT\fR time is
  1697. Xearlier than the current time, then the result is negative.
  1698. X.TP
  1699. X.B %5
  1700. Xis replaced with "\fIma\fR" where \fIma\fR is the absolute value of the number
  1701. Xproduced by \fB%4\fR.
  1702. X.TP
  1703. X.B %6
  1704. Xis replaced with "ago" or "from now", depending on the relationship between
  1705. Xthe \fIAT\fR time and the current time.
  1706. X.TP
  1707. X.B %7
  1708. Xis replaced with the number of hours between the \fIAT\fR time and the
  1709. Xcurrent time.  It is always non-negative.
  1710. X.TP
  1711. X.B %8
  1712. Xis replaced with the number of minutes between the \fIAT\fR time and
  1713. Xthe current time, after the hours (\fB%7\fR) have been subtracted out.
  1714. XThis is a number ranging from 0 to 59.
  1715. X.TP
  1716. X.B %9
  1717. Xis replaced with "s" if the value produced by \fB%8\fR is not 1.
  1718. X.TP
  1719. X.B %0
  1720. Xis replaced with "s" if the value produced by \fB%7\fR is not 1.
  1721. X.TP
  1722. X.B %!
  1723. Xis replaced with "is" if the current time is before the \fIAT\fR time,
  1724. Xor "was" if it is after.
  1725. X.TP
  1726. X.B 
  1727. X%"
  1728. X(percent-doublequote) is removed.  This sequence is not 
  1729. Xused by the substitution filter,
  1730. Xbut is used to tell \fBremind\fR which text to include in a calendar
  1731. Xentry when the \fB\-c\fR option is chosen.  See the section "Producing
  1732. Xa Calendar"
  1733. X.PP
  1734. XNotes:
  1735. X.TP
  1736. Xo
  1737. X.B Remind
  1738. Xnormally prints a blank line after each reminder; if the last character
  1739. Xof the body is '%', the blank line will not be printed.
  1740. X.TP
  1741. Xo
  1742. XSubstitutions a, b, c, e, f, g, h, i, j, k, l, u and v all are replaced
  1743. Xwith "today" if the current date equals the trigger date, or "tomorrow"
  1744. Xif the trigger date is one day after the current date.  Thus, they are
  1745. X.B not
  1746. Xthe same as substitutions built up from the simpler %w, %y, etc.
  1747. Xsequences.
  1748. X.TP
  1749. Xo
  1750. XAny of the substitutions dealing with time (0 through 9 and '!')
  1751. Xproduce undefined results if used in a reminder which does not have
  1752. Xan \fIAT\fR keyword.  Also, if a reminder has a \fIdelta\fR and may
  1753. Xbe triggered on several days, the time substitutions ignore the date.  Thus,
  1754. Xthe \fB%1\fR substitution may report that a meeting is in 15 minutes, for
  1755. Xexample, even though it may only be in 2 days time, because a \fIdelta\fR has
  1756. Xtriggered the reminder.  It is recommended that you use the time substitutions
  1757. Xonly in timed reminders with no \fIdelta\fR which are designed to be
  1758. Xqueued for timed activation.
  1759. X.TP 
  1760. Xo
  1761. XCapital letters can be used in the substitution sequence, in which case
  1762. Xthe first character of the substituted string is capitalized (if it is
  1763. Xnormally a lower-case letter.)
  1764. X.TP 
  1765. Xo
  1766. XAll other characters following a "%" sign are simply copied.  In particular,
  1767. Xto get a "%" sign out, use "%%" in the body.  To start the body of a reminder
  1768. Xwith a space, use "% ", since
  1769. X.B remind
  1770. Xnormally scans for the first non-space character after a
  1771. X.I MSG
  1772. Xor
  1773. X.I RUN
  1774. Xtoken.
  1775. X.SH PRODUCING A CALENDAR
  1776. XIf you provide the \fB\-c\fR option, the \fBremind\fR will scan your
  1777. Xreminder file and produce a calendar with your reminders entered on the
  1778. Xappropriate dates.
  1779. X.PP
  1780. XWhen you produce a calendar, \fBremind\fR will pass the text
  1781. Xthrough the substitution mechanism.  However, you may indicate to \fBremind\fR
  1782. Xwhich portions of the text should be placed in the calendar.  This is done
  1783. Xwith the \fB%"\fR sequence.  Here's an example:
  1784. X.PP
  1785. X.nf
  1786. X    REM 6 Jan +6 MSG %"David's birthday%" is %a.
  1787. X.fi
  1788. X.PP
  1789. XWhen you run \fBremind\fR normally, it executes the reminder as if the
  1790. X.B 
  1791. X%"
  1792. Xsequences were not there.  When you produce a calendar with the \fB\-c\fR
  1793. Xoption, however, only the text "David's birthday" is entered into the
  1794. Xcalendar.  For convenience, timed reminders are sorted by time before
  1795. Xbeing entered into the calendar, and the time of each reminder is printed
  1796. Xbefore the reminder text.
  1797. X.PP
  1798. XNote that by default, only \fIMSG\fR reminders are included in the calendar; 
  1799. X\fIRUN\fR reminders are ignored.  However, if you explicitly place the %"
  1800. Xescape sequences in a \fIRUN\fR reminder, then it will be included in the
  1801. Xcalendar.
  1802. XIf you indicate empty text for the calendar entry
  1803. Xwith the sequence \fB%"%"\fR, then the reminder is ignored when producing
  1804. Xthe calendar, whether is is a \fIMSG\fR or \fIRUN\fR type.
  1805. X.PP
  1806. XIf your reminder file has errors in it, when you produce a calendar, you
  1807. Xwill get many error messages apparently coming from the file "*cache*"
  1808. XThis is because \fBremind\fR caches the reminder file for efficient
  1809. Xproduction of the calendar.  Thus, you should check that your reminder
  1810. Xfile is error-free (by running \fBremind\fR with the \fB\-d\fR option)
  1811. Xbefore attempting to produce a calendar.
  1812. X.PP
  1813. XThe "Simple Calendar" format is useful if you want to format the calendar
  1814. Xwith another program.  You can save this output to a file or pipe it to
  1815. Xyour formatting program.  The output format is:
  1816. X.PP
  1817. X.nf
  1818. X    yyyy/mm/dd: hr:min \fIbody\fR
  1819. X.fi
  1820. X.PP
  1821. XThe \fIhr:min\fR portion is present only if the reminder has an \fIAT\fR
  1822. Xclause.  You can produce this format by using the \fB\-s\fR option in
  1823. Xconjunction with the \fB-c\fR option.  The \fB\-n\fR option produces
  1824. Xa listing in this format also; however, it is not sorted by date, and
  1825. Xindicates the next occurrence of each reminder in the reminder file.
  1826. X.SH THE BANNER COMMAND
  1827. XWhen
  1828. X.B remind
  1829. Xissues reminders, it normally prints a message saying:
  1830. X.PP
  1831. X"Reminders for \fIweekday, day-th month, year\fR (today):"
  1832. X.PP
  1833. X(If you supply a date on the command line different from the system date,
  1834. Xthe "(today)" portion is omitted.)
  1835. X.PP
  1836. XYou can change this default to anything you want with the
  1837. X.I BANNER
  1838. Xcommand.  It should appear in the reminder file before any
  1839. X.I REM
  1840. Xcommands.  (This is not enforced, but a
  1841. X.I BANNER
  1842. Xcommand encountered after a reminder has been triggered will be ignored.)
  1843. X.PP
  1844. XThe format of
  1845. X.I BANNER
  1846. Xis:
  1847. X.PP
  1848. XBANNER
  1849. X.I string
  1850. X.PP
  1851. XThe
  1852. X.I string
  1853. Xis passed through the substitution mechanism described before, using the
  1854. Xcurrent date and time for substitution.  The standard banner is described by:
  1855. X.PP
  1856. X.nf
  1857. X    BANNER Reminders for %w, %d%s %m, %y%o:
  1858. X.fi
  1859. X.PP
  1860. XYou can have a blank banner by using:
  1861. X.PP
  1862. X.nf
  1863. X    BANNER %
  1864. X.fi
  1865. X.PP
  1866. X.SH PURGING REMINDER FILES
  1867. XYou should periodically purge your reminder file of "expired"
  1868. X.I REM
  1869. Xcommands and global
  1870. X.I OMITs.
  1871. XThese are reminders which took place in the past and can never occur
  1872. Xagain, or
  1873. X.I OMITs
  1874. Xwhich are for past years.  Of course, only
  1875. X.I REMs
  1876. Xand
  1877. X.I OMITs
  1878. Xwith the
  1879. X.I year
  1880. Xspecified can ever expire.
  1881. X.PP
  1882. XTo purge your reminder file, run
  1883. X.B remind
  1884. Xin
  1885. X.I purge
  1886. Xmode.  This mode simply echoes non-expired lines to standard output, and
  1887. Xexpired lines to standard error.  Thus, to purge a file, you could type:
  1888. X.PP
  1889. X.nf
  1890. X    REMIND -p notes.old > notes.new
  1891. X.fi
  1892. X.PP
  1893. XThe file "notes.new" would contain all non-expired lines from "notes.old."
  1894. XAll expired lines are echoed to the screen.
  1895. X.I INCLUDEd
  1896. Xfiles are read and processed, but not purged.  You must purge each
  1897. X.I INCLUDEd
  1898. Xfile separately.
  1899. X.PP
  1900. XYou can supply a date on the command line when purging, but beware:  If you
  1901. Xsupply a date in the future, you may inadvertently purge lines which have not
  1902. Xreally expired yet.
  1903. X.SH DEBUGGING A REMINDER FILE
  1904. XThe debug command-line option \-d is used to debug reminder files.  It tells
  1905. Xyou useful information about the reminder file.  It displays the trigger date
  1906. Xof each reminder, and places an asterisk by those which would be issued
  1907. Xon the current date.  It also informs you of
  1908. X.I OMITs
  1909. Xwhich have expired, and gives warnings about situations which could lead
  1910. Xto long execution times or unexpected results.
  1911. X.PP
  1912. XAll debugging messages are sent to standard error.
  1913. X.SH EXAMPLES OF REMINDERS
  1914. XThis section is a sampling of what you can do with \fBremind\fR.
  1915. X.PP
  1916. X.nf
  1917. X    REM 5 Feb 1991 AT 14:00 +45 *30 \\
  1918. X    RUN mail -s "Meeting at %2" $LOGNAME </dev/null &
  1919. X.fi
  1920. X.PP
  1921. XOn 5 February, 1991, this reminder will mail 
  1922. Xyou reminders of a 2:00pm meeting at 1:15, 
  1923. X1:45 and 2:00.  The subject of the mail message will be "Meeting at 2:00pm"
  1924. Xand the body of the message will be blank.
  1925. X.PP
  1926. X.nf
  1927. X    REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless -g +0+0 &
  1928. X.fi
  1929. X.PP
  1930. XThis reminder will pop up an xless window at 5:00pm every day.  The xless
  1931. Xwindow will contain the line "5:00pm - GO HOME!"
  1932. X.PP
  1933. X.nf
  1934. X    REM AT 23:59 RUN (sleep 120; remind -a .reminders) &
  1935. X.fi
  1936. X.PP
  1937. XThis reminder will run at one minute to midnight.  It will cause a new
  1938. Xremind process to start at one minute past midnight.  This allows you to
  1939. Xhave a continuous reminder service so you can work through the night and
  1940. Xstill get timed reminders for early in the morning.
  1941. X.PP
  1942. X.nf
  1943. X    remind -c12 /dev/null 1 Jan 1991
  1944. X.fi
  1945. X.PP
  1946. XThis invocation of \fBremind\fR will cause it to print a calendar for
  1947. X1991, with all entries left blank.
  1948. X.SH AUTHOR
  1949. XDavid F. Skoll
  1950. X.SH BUGS
  1951. X.B Remind
  1952. Xwas originally written for MS-DOS and ported to UNIX.  It does some things
  1953. Xin an ungainly way.
  1954. X.PP
  1955. XDate calculation algorithms are fairly "brute force."
  1956. X.PP
  1957. XThe MS-DOS version of \fBremind\fR does not support queuing or timed
  1958. Xactivation of reminders.  It does, however, support the other semantics
  1959. Xof the \fIAT\fR keyword.
  1960. X.PP
  1961. X.B Remind
  1962. Xhas some built-in limits on total line length (511 characters),
  1963. Xthe length of an expanded \fIREM\fR body (511 characters), the number
  1964. Xof global \fIOMIT\fRs, etc.
  1965. END_OF_FILE
  1966. if test 40229 -ne `wc -c <'remind.1'`; then
  1967.     echo shar: \"'remind.1'\" unpacked with wrong size!
  1968. fi
  1969. # end of 'remind.1'
  1970. fi
  1971. echo shar: End of archive 1 \(of 4\).
  1972. cp /dev/null ark1isdone
  1973. MISSING=""
  1974. for I in 1 2 3 4 ; do
  1975.     if test ! -f ark${I}isdone ; then
  1976.     MISSING="${MISSING} ${I}"
  1977.     fi
  1978. done
  1979. if test "${MISSING}" = "" ; then
  1980.     echo You have unpacked all 4 archives.
  1981.     rm -f ark[1-9]isdone
  1982. else
  1983.     echo You still need to unpack the following archives:
  1984.     echo "        " ${MISSING}
  1985. fi
  1986. ##  End of shell archive.
  1987. exit 0
  1988. exit 0 # Just in case...
  1989. -- 
  1990. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1991. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1992. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1993. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1994.